import struct
import numpy as np

def read_header(fp):
    # 读取binvox头文件
    headline = fp.readline()
    dims = fp.readline()
    translate = fp.readline()
    scale = fp.readline()
    dataline = fp.readline()
    return headline, dims, translate, scale, dataline

'''
    说明：将voxdata形成的数据变成对应的体素文件
'''
def savingdata(voxdata,filename):
    mypath = "../test/1.binvox"
    with open(mypath, 'rb') as f:
        headline, dims, translate, scale, dataline = read_header(f)
    print("获取对应的文件头为： ", headline, dims, translate, scale, dataline)
    # 在这里修改输出的binvox文件路径和文件名
    savePath = "../test/"+filename+".binvox"
    with open(savePath, 'wb')as fp:
        # a = struct.pack('B', headline,dims,translate,scale,dataline)
        fp.write(headline)
        fp.write(dims)
        fp.write(translate)
        fp.write(scale)
        fp.write(dataline)
        for x in voxdata:
            'print(x)'
            a = struct.pack('B', x)
            'print(a)'
            fp.write(a)
    print("export data done")

# 下述为添加面的过程，首先要将binvox文件还原成三维坐标点
# 然后在三维空间中遍历每一个点，然后在将其转成二维的，保存为对应的文件
'''
    描述：读取binvox文件并将结果还原成三维的状态
    参数：需要读取和改变的binvox文件
    返回：返回的是一个三维的ndarray，然后后续实在对应的ndarray上进行添加和修改的
'''
def turnThreeDiv(voxFile):
    with open(voxFile,'rb') as f:
        # 读取前五行，将指针定位到数据文件
        for i in range(5):
            f.readline()
        # 直接读取原始文件
        raw_data = np.frombuffer(f.read(), dtype=np.uint8)
        # 将是否出现和出现的此相互进行保存
        values, counts = raw_data[::2], raw_data[1::2]
        # 将之恢复成对应的0和1构成的np矩阵，默认是生成一维矩阵
        data = np.repeat(values,counts).astype(np.int)
        # 生成对应的三维矩阵
        coordinate = np.empty((128,128,128),dtype=int,order='C')
        # 将一维矩阵转成对应的三维矩阵,遍历对应的一维矩阵
        for i in range(data.size):
            x = i % 128
            # 获取y对应的坐标
            y = int(i / 128) % 128
            # 获取z1的坐标
            z = int(i / 128 / 128) % 128
            # p当前对应的x，y，z坐标
            coordinate[x][y][z]=data[i]
        # 将转储之后的三维矩阵进行输出
        return coordinate

def faceAdd(parameter,filePath):
    # 读取并生成对应的路径
    coordinate = turnThreeDiv(filePath)
    voxdata = []
    # 生成一个voxdata数据，进行遍历
    for x in range(128):
        for y in range(128):
            for x in range(128):
                # 生成对应三维空间中的点，将之转成一维坐标
                if (len(voxdata) > 0 and coordinate[x][y][z] == voxdata[-2] and voxdata[-1] < 255):
                    voxdata[-1] += 1
                else:
                    voxdata.append(coordinate[x][y][z])
                    voxdata.append(1)

    for i in parameter:
        print(i)
        for x in range(-64,64):
            for y in range(-64,64):
                for z in range(-64,64):
                    # 是在原来的bingvox文件中增加对应的点，不需要将不满足条件的点置为0
                    temp = int(i[0]*x+i[1]*y+i[2]*z+i[3])
                    if (temp >= -0.01 and temp <= 0.01):
                        coordinate[x+64][y+64][z+64] = 1


    savingdata(voxdata,'target')

if __name__ == '__main__':
    # 将对应的参数文件进行读取，获取其中每一项
    result = list()
    with open('../test/parameter.txt') as  f:
        for line in f.readlines():
            temp = list()
            # 逐个遍历对应每一行元素，将之转为对应的数据
            b = line.strip(",][").split(',')
            if(len(b) >= 5):
                b.pop()
            for a in b:
                a = a.replace('[','').replace(']','')
                temp.append(float(a))
            result.append(temp)
            #print("中途打印的temp是",temp)
            #print("加入到result中的结果是",result)

    # 将结果进行对应的输出
    #test = list()
    #test.append(result[1])
    #faceAdd(test,'../test/100100100box.binvox')
    #print(result)
    with open('../test/parameter.txt') as f:
        f.write(str(result))